#include "Tag.h"
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include "GraphicsScene.h"
#include "Node.h"

//-------------------------------------

Tag::Tag( GraphicsObject * parent, QString t ) :
    TagBase(),
    fnt( TAG_DEFAULT_FONT_FAMILY, TAG_DEFAULT_FONT_SIZE, QFont::Bold ),
    showParamStr( true ),
    sp( 0 )
{
    shownPramList.clear();
    owner = parent;
    //SetText( t );
    rect = QRectF( 0, 0, 1, 1 );
    setFlags( ItemIsSelectable | ItemIsMovable | ItemSendsScenePositionChanges | ItemSendsGeometryChanges );
    setAcceptsHoverEvents( true );
    setCursor( Qt::PointingHandCursor );
    setSelected( false );
    ResizingPoints( rpHide );
    if( owner )
    {
        sp = owner->GetScene()->GetShowParam();
        owner->AddTag( this );
    }
    paramStr = "";
    pvs.clear();
    opt = QTextOption( Qt::AlignCenter );
    opt.setWrapMode( QTextOption::WordWrap );
}

//-------------------------------------

void Tag::paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
{
    if( !_show )
        return;

    painter->save();
    painter->setPen( QPen( clr, TAG_BORDER_WIDTH ) );
    painter->setBrush( QBrush( clr, Qt::NoBrush ) );

    if( sp->ShowTagBorder )
        painter->drawRect( rect );

    painter->setFont( fnt );

    if( pvs.count() )
    {
        QString val = this->GetText() + "\n\n";
        PVIter it = pvs.begin();
        while( it != pvs.end() )
        {
            val = val + (*it)->svalue + "\n";
            ++it;
        }
        adjustRect( val );
        painter->drawText( rect, val, opt );
    }
    else
        painter->drawText( rect, this->getTagText(), opt );

    //painter->restore();

    if( option->state & QStyle::State_Selected )
    {
        painter->setBrush( Qt::NoBrush );
        painter->setPen( clSelectDef );

        painter->drawRect( rect );
    }
}

//-------------------------------------

QRectF Tag::boundingRect() const
{
    return rect.united( childrenBoundingRect() );
}

//-------------------------------------

QVariant Tag::itemChange( GraphicsItemChange change, const QVariant & value )
{
    if( change == ItemSelectedHasChanged )
    {
        ResizingPoints( rpUpdate );
        if( value.toBool() )
        {
            ResizingPoints( rpShow );
            setZValue( 2 );
        }
        else
        {
            ResizingPoints( rpHide );
            setZValue( 0 );
        }
    }
    if( change == ItemScenePositionHasChanged )
    {
        //emit moved( value.toPointF() );
    }
    return value;
}

//-------------------------------------

QString Tag::getTagText()
{
    QString str;
    if( paramStr.isEmpty() )
        str = GetText();
    else
    {
        if( shownPramList.count() )
        {
            QStringList tmp = paramStr.split( "\n" );
            QString line;
            paramStr.clear();
            for( int i=0; i < tmp.count(); i++ )
            {
                line = tmp.at(i);
                if( showParam( line ) )
                {
                    if( line.contains( "Name = " ) )
                        line = line.mid( 7, line.count()-7 );
                    paramStr += line + "\n";
                }
            }
        }
        str = QString( "" ).append( GetText() ).append("\n").append( paramStr );
    }
    adjustRect( str );
    return str;
}

//-------------------------------------

void Tag::adjustRect( const QString & str )
{
    QRectF newRect( 0,0,1,1 );
    QStringList sl = str.split( "\n" );
    int maxLen = 0;
    int currLen;
    QString maxLenStr;
    for( int i=0; i < sl.count(); i++ )
    {
        currLen = sl.at( i ).length();
        if( maxLen < currLen )
        {
            maxLen = currLen;
            maxLenStr = sl.at( i );
        }
    }
    QFontMetrics fntInf( fnt );
    int w = fntInf.width( maxLenStr.toAscii() ) + fnt.pointSizeF();
    int h = fntInf.height() * sl.count();
    newRect.setWidth( w );
    newRect.setHeight( h );
    Resize( newRect );
    ResizingPoints( rpHide );
    scene->Update();
}

//-------------------------------------

bool Tag::showParam( const QString & p )
{
    for( int i=0; i < shownPramList.count(); i++ )
    {
        if( p.contains( shownPramList.at(i) ) )
            return true;
    }
    return false;
}

//-------------------------------------

void Tag::SetParamStr( const QString & s )
{
    paramStr = s;
/*
    if( shownPramList.count() )
        return;

    QStringList lines = paramStr.split( "\n" );
    QRegExp words( "(\\w+)" );
    for( int i=0; i < lines.count(); i++ )
    {
        int pos = words.indexIn( lines.at(i) );
        if( pos > -1 )
        {
            shownPramList.append( words.cap(0) );
        }
    }
*/
}

//-------------------------------------

ProcessVariable * Tag::GetProcessVariable( int idf )
{/*
    for( int i=0; i < pvs.count(); i++ )
    {
        if( pvs.at( i )->idf == idf )
        {
            return pvs.at( i );
        }
    }
*/
    if( pvs.contains( idf ) )
        return pvs[ idf ];
    return 0;
}

//-------------------------------------

void Tag::AddProcessVariable( ProcessVariable * pv )
{
    if( pvs.contains( pv->idf ) )
        return;
    pvs[ pv->idf ] = pv;
    QString s = "#" + QString().setNum( pv->idf );
    if( !shownPramList.contains( s ) )
        shownPramList.append( s );
}

//-------------------------------------

void Tag::RmProcessVariable( ProcessVariable * pv )
{
    if( pvs.contains( pv->idf ) )
    {
        pvs.remove( pv->idf );
        shownPramList.removeAll( "#" + QString().setNum( pv->idf ) );
    }
}

//-------------------------------------

void Tag::UpdateParamStr()
{
    if( sp )
    {
        if( dynamic_cast< Node* >( owner ) )
            _show = sp->ShowNodeTags;
        else
            _show = sp->ShowBranchTags;
    }
}

//-------------------------------------




